package com.john.utils.common;

import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 类描述：时间操作定义类
 */
public class DateUtils extends PropertyEditorSupport {
	public static final SimpleDateFormat date_sdf = new SimpleDateFormat("yyyy-MM-dd");
	public static final SimpleDateFormat date_sdfs = new SimpleDateFormat("yyyy-MM");
	public static final SimpleDateFormat date_yyyy = new SimpleDateFormat("yyyy");
	public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
	public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat("yyyy年MM月dd日");
	public static final SimpleDateFormat time_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
	public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat("HH:mm");
	public static final  SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final String dtLong = "yyyyMMddHHmmss";
	private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
	private static final long HOUR_IN_MILLIS = 3600 * 1000;
	private static final long MINUTE_IN_MILLIS = 60 * 1000;
	private static final long SECOND_IN_MILLIS = 1000;

	/**
	 * 获取前一天
	 * @return
	 */
	public static String getDateYesterDay(){
		try {
			Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
			ca.setTime(new Date());
			ca.add(Calendar.DATE, -1);
			Date lastMonth = ca.getTime(); //结果
			return date_sdf.format(lastMonth);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 指定模式的时间格式
	private static SimpleDateFormat getSDFormat(String pattern) {
		return new SimpleDateFormat(pattern);
	}

	/**
	 * 系统当前日期，具体格式：年-月-日
	 */
	public static String formatNewDate() {
		return date_sdf.format(getCalendar().getTime());
	}

	/**
     * 系统当前日期
     * @param dateFormat 自定义日期格式
     */
    public static String getCurrentDate(String dateFormat) {
        return new SimpleDateFormat(dateFormat).format(new Date());
    }

	/**
	 * 毫秒转化分
	 */
	public static String strSecond(long ms) {
		int ss = 1000;
        int mi = ss * 60;  
        int hh = mi * 60;  
        int dd = hh * 24;  
        long day = ms / dd;  
        long hour = (ms - day * dd) / hh;  
        long minute = (ms - day * dd - hour * hh) / mi;  
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;  
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;  
        String strDay = day < 10 ? "0" + day : "" + day; //天  
        String strHour = hour < 10 ? "0" + hour : "" + hour;//小时  
        String strMinute = minute < 10 ? "0" + minute : "" + minute;//分钟  
        String strSecond = second < 10 ? "0" + second : "" + second;//秒  
        String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒  
        strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;  
        return strSecond;
	}


	/**
	 * 时间戳转换成日期
	 * @param str    时间戳字符串
	 * @param dateFormat 自定义日期格式
	 */
	public static String strTimesDate(String str,String dateFormat){
		if(StringUtil.isEmpty(str)){
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		Long time=Long.parseLong(str);
		String d = format.format(time);
		return d;
	}

	/**
	 * 当前日历，这里用中国时间表示
	 */
	public static Calendar getCalendar() {
		return Calendar.getInstance();
	}

	/**
	 * 指定毫秒数表示的日历
	 * @param millis 毫秒数
	 */
	public static Calendar getCalendar(long millis) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date(millis));
		return cal;
	}

	/**
	 * 当前日期
	 * @return 系统当前时间
	 */
	public static Date getgetNewDate() {
		return new Date();
	}

	/**
	 * 指定毫秒数表示的日期
	 * @param millis 毫秒数
	 */
	public static Date getDate(long millis) {
		return new Date(millis);
	}

	/**
	 * 时间戳转换为字符串
	 * @param time Timestamp
	 */
	public static String timestampToStr(Timestamp time) {
		Date date = null;
		if (null != time) {
			date = new Date(time.getTime());
		}
		return dateToStr(date,date_sdf.toPattern());
	}

	/**
	 * 字符串转换时间戳
	 * @param time
	 */
	public static Timestamp strToTimestamp(String time) {
		return new Timestamp(Long.parseLong(time));
	}

	/**
	 * 字符串转换成日期
	 * @param str
	 */
	public static Date strToDate(String str, String dateFormat) {
		if (null == str || "".equals(str)) {
			return null;
		}
		try {
			Date date = new SimpleDateFormat(dateFormat).parse(str);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 格式化时间
	 * @param data
	 * @param dateFormat
	 */
	public static String dataFormat(String data,String dateFormat){
		SimpleDateFormat sformat = new SimpleDateFormat(dateFormat);
		Date date=null;
		try {
			date=sformat.parse(data);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sformat.format(date);
	}

	/**
	 * 日期转换为字符串
	 * @param date 日期
	 * @param dateFormat 日期格式
	 */
	public static String dateToStr(Date date ,String dateFormat) {
		if (null == date) {
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		return format.format(date);
	}

	/**
	 * 日期转换为字符串
	 * @param dateFormat  日期格式
	 */
	public static String getNewDate(String dateFormat) {
		Date date=new Date();
		if (null == date) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(date);
	}

	/**
	 * 指定毫秒数的时间戳
	 * @param millis 毫秒数
	 * @return 指定毫秒数的时间戳
	 */
	public static Timestamp getTimestamp(long millis) {
		return new Timestamp(millis);
	}


	/**
	 * 系统当前的时间戳
	 *
	 * @return 系统当前的时间戳
	 */
	public static Timestamp getTimestamp() {
		return new Timestamp(new Date().getTime());
	}

	/**
	 * 指定日期的时间戳
	 * @param date 指定日期
	 */
	public static Timestamp getTimestamp(Date date) {
		return new Timestamp(date.getTime());
	}

	/**
	 * 指定日历的时间戳
	 * @param cal 指定日历
	 */
	public static Timestamp getCalendarTimestamp(Calendar cal) {
		return new Timestamp(cal.getTime().getTime());
	}


	/**
	 * 系统时间的毫秒数
	 */
	public static long getMillis() {
		return new Date().getTime();
	}

	/**
	 * 指定日历的毫秒数
	 * @param cal 指定日历
	 */
	public static long getMillis(Calendar cal) {
		return cal.getTime().getTime();
	}

	/**
	 * 指定日期的毫秒数
	 * @param date 指定日期
	 */
	public static long getMillis(Date date) {
		return date.getTime();
	}

	/**
	 * 指定时间戳的毫秒数
	 * @param ts  指定时间戳
	 */
	public static long getMillis(Timestamp ts) {
		return ts.getTime();
	}

	/**
	 * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
	 *
	 * @param src 将要转换的原始字符窜
	 * @param pattern  转换的匹配格式
	 */
	public static Date parseDate(String src, String pattern)
			throws ParseException {
		return getSDFormat(pattern).parse(src);

	}

	/**
	 * 比较两个日期差
	 * @param startTime    3开始日期
	 * @param endTime 结束日期
	 * @return map 键 day天  hour 时  min 分 sec 秒
	 */
	public static Map dateDiff(String startTime, String endTime,String format) {
        // 按照传入的格式生成一个simpledateformate对象    
        SimpleDateFormat sd = new SimpleDateFormat(format);
        SimpleDateFormat sd1 = new SimpleDateFormat("HH");
        Map<String, Object> map = new HashMap<String, Object>();
        long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数    
        long nh = 1000 * 60 * 60;// 一小时的毫秒数    
        long nm = 1000 * 60;// 一分钟的毫秒数    
        long ns = 1000;// 一秒钟的毫秒数    
        long diff;    
        long day = 0;    
        long hour = 0;    
        long min = 0;    
        long sec = 0;    
        // 获得两个时间的毫秒时间差异    
        try {    
            diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();    
            day = diff / nd;// 计算差多少天    
            hour = diff % nd / nh + day * 24;// 计算差多少小时    
            min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟    
            sec = diff % nd % nh % nm / ns;// 计算差多少秒    
            // 输出结果    
            map.put("day",day);
            map.put("hour", (hour - day * 24));
            map.put("min",(min - day * 24 * 60));
            map.put("sec", sec);
            map.put("startHour",Integer.valueOf(sd1.format(sd.parse(startTime))));
            map.put("endHour", Integer.valueOf(sd1.format(sd.parse(endTime))));
            return map;
   
        } catch (ParseException e) {    
            // TODO Auto-generated catch block    
            e.printStackTrace();    
        }    
       return null;
	}

	/**
	 * 获取当月的所有日期
	 */
	public static List<String> getDayListOfMonth(int months) {
		try {
			List<String> list = new ArrayList<String>();
			Calendar aCalendar = Calendar.getInstance();
			aCalendar.setTime(date_sdf.parse(getCurrentDate(date_yyyy.toPattern()) + "-" + months + "-" + "01"));
			aCalendar.add(months,0);
			int year = aCalendar.get(Calendar.YEAR);//年份
			int month = aCalendar.get(Calendar.MONTH) + 1;//月份
			int day = aCalendar.getActualMaximum(Calendar.DATE);
			for (int i = 1; i <= day; i++) {
				String aDate = String.valueOf(year)+"-"+month+"-"+i;
				list.add(aDate);
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据当前日期获取月份
	 * @param currentDate 年月日
	 * @param type 2上月 1本月
	 */
    public static int getLastDate(String currentDate,String type) {  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
        Date date = null;  
        try {  
            date = sdf.parse(currentDate + "-" + "01");  
        } catch (ParseException e) {  
            e.printStackTrace();  
        }  
        Calendar c = Calendar.getInstance();  
        c.setTime(date);  
        c.add(Calendar.MONTH,0);  
        int lastDate = (c.get(Calendar.MONTH) + 1); 
        if(type.equals("2")){
			lastDate = (c.get(Calendar.MONTH));
        }
        return lastDate;  
    } 
    
    /** 
    * 根据当前日期获得所在周的日期区间（周一,周日日期） 
    */
    public static String getTimeInterval(String date) {  
         try {
			 Calendar cal = Calendar.getInstance();
             Date dates = parseDate(date, date_sdf.toPattern());
             cal.setTime(dates);  
             // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了  
             int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天  
             if (1 == dayWeek) {  
                cal.add(Calendar.DAY_OF_MONTH, -1);  
             }  
             // System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期  
             // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一  
             cal.setFirstDayOfWeek(Calendar.MONDAY);  
             // 获得当前日期是一个星期的第几天  
             int day = cal.get(Calendar.DAY_OF_WEEK);  
             // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值  
             cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);  
             String imptimeBegin = date_sdf.format(cal.getTime());  
             // System.out.println("所在周星期一的日期：" + imptimeBegin);  
             cal.add(Calendar.DATE, 6);  
             String imptimeEnd = date_sdf.format(cal.getTime());  
             // System.out.println("所在周星期日的日期：" + imptimeEnd);  
             return imptimeBegin + "," + imptimeEnd;
		 } catch (Exception e) {
			 e.printStackTrace();
		 }
        return null;
    }  
    
    /** 
    * 根据当前日期获得上周的日期区间（上周周一,周日日期） 
    * @param type 1上周 2下周
    */
    public static String getLastTimeInterval(String date,String type) {  
         try {
			 Calendar calendar1 = Calendar.getInstance();
             Date dates = parseDate(date, date_sdf.toPattern());
             calendar1.setTime(dates);  
             Calendar calendar2 = Calendar.getInstance();  
             int dayOfWeek = calendar1.get(Calendar.DAY_OF_WEEK) - 1;  
             int offset1 = 1 - dayOfWeek;  
             int offset2 = 7 - dayOfWeek;  
             if(type.equals("1")){
				 calendar1.add(Calendar.DATE, offset1 - 7);
             }else{
				 calendar1.add(Calendar.DATE, offset1 + 7);
             }
             calendar2.add(Calendar.DATE, offset2 - 7);  
             String lastBeginDate = date_sdf.format(calendar1.getTime());  
             String lastEndDate = date_sdf.format(calendar2.getTime());  
             return lastBeginDate + "," + lastEndDate;
		 } catch (Exception e) {
			 e.printStackTrace();
		 }
        return null;
    }  
    
    /**
     * 获取周的所有日期
     * @param date
     */
    public static List<String> getDaysDate(String date){
		try {
			List<String> list = new ArrayList<String>();
			Calendar aCalendar = Calendar.getInstance();
			Date dates = parseDate(date, date_sdf.toPattern());
			aCalendar.setTime(dates);
			// 今天是一周中的第几天
			int dayOfWeek = aCalendar.get(Calendar.DAY_OF_WEEK );
			if (aCalendar.getFirstDayOfWeek() == Calendar.SUNDAY) {
				aCalendar.add(Calendar.DAY_OF_MONTH, 1);
			}
			// 计算一周开始的日期
			aCalendar.add(Calendar.DAY_OF_MONTH, -dayOfWeek);
			for (int i=1;i<=7;i++) {
				aCalendar.add(Calendar.DAY_OF_MONTH, 1);
				list.add(date_sdf.format(aCalendar.getTime()));
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }
    
    /**
     * 根据日期获取上月月初日期,月末日期
     * @param date 年月日
     * @param type 1 下月 2上月
     */
    public static String getPrevMonth(String date,String type){
		try {
			Calendar aCalendar = Calendar.getInstance();
			Date dates = parseDate(date, date_sdf.toPattern());
			aCalendar.setTime(dates);
			aCalendar.add(Calendar.MONTH,type.equals("1") ? -1 : +1);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			int lastMonthMaxDay=aCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
			aCalendar.set(aCalendar.get(Calendar.YEAR), aCalendar.get(Calendar.MONTH), lastMonthMaxDay, 23, 59, 59);

			//按格式输出
			String gtime = sdf.format(aCalendar.getTime()); //上月最后一天
			SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-01");
			String gtime2 = sdf2.format(aCalendar.getTime()); //上月第一天
			return gtime2+","+gtime;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }

	/**
	 * 字符串日期效验
	 * @param date 日期
	 * @param toFormat 格式
	 * @return yes true not false
	 */
	public static boolean isValidDate(String date,String toFormat) {
		if(StringUtil.isEmpty(date) || StringUtil.isEmpty(toFormat)){
			return false;
		}
		boolean convertSuccess=true;
		// 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
		SimpleDateFormat format = new SimpleDateFormat(toFormat);
		try {
			// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(date);
		} catch (ParseException e) {
			// e.printStackTrace();
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess=false;
		}
		return convertSuccess;
	}

	public static void main(String[] args) throws ParseException {
		// System.out.println(isValidDate(null,DateUtils.yyyyMMddHHmmss.toPattern()));
		Date date = parseDate("2024-03-12T16:50:31+08:00","yyyy-MM-dd'T'HH:mm:ssXXX");
		System.out.println(dateToStr(date,"yyyy-MM-dd'T'HH:mm:ss"));

		// 2022-09-07 00:30:37
		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
		// 2022-09-07T00:30:37+0800
		System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(date));
		//2024-03-11T10:41:02+08:00 yyyy-MM-DDTHH:mm:ss+TIMEZONE
		System.out.println("2024-03-11T10:41:02+08:00");
	}

}